package cn.itcast.web.utils;

import cn.itcast.domain.system.SysLog;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.SysLogService;
import cn.itcast.web.controller.BaseController;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;

/*
 日志的切面类
 */
@Component
@Aspect //该类是一个切面类
public class LogAspect  {

    @Autowired
    private SysLogService sysLogService;


    @Autowired
    private HttpServletRequest request;


    /*
        环绕通知的要求：
                1. 方法的返回值类型一定是Object，这里的返回值代表了目标方法的返回值
                2. 方法一定要有形参ProceedingJoinPoint ,ProceedingJoinPoint 代表的是目标方法
     */
    //切入点表达式是可以使用逻辑运算符
    @Around("execution(* cn.itcast.web.controller.*.*.*(..)) &&!  execution(* cn.itcast.web.controller.*.SysLogController.*(..))")
    public Object saveLog(ProceedingJoinPoint pj){

        try {
            Object result = pj.proceed();//放行目标方法
            //做日志
            SysLog sysLog = new SysLog();
            //给日志补充数据
            sysLog.setId(UUID.randomUUID().toString());
            //得到session
            User loginUser = (User) request.getSession().getAttribute("loginUser");
            //设置登陆者名字
            sysLog.setUserName(loginUser.getUserName());
            //设置ip
            sysLog.setIp(request.getRemoteAddr());
            //设置时间
            sysLog.setTime(new Date());
            //设置当前执行的方法
            String methodName = pj.getSignature().getName();// pj.getSignature().得到方法的签名
            sysLog.setMethod(methodName);
            //设置方法所属的类名
            //   pj.getTarget()  获取当前调用方法的目标对象
            String className = pj.getTarget().getClass().getName();
            sysLog.setAction(className);
            sysLog.setCompanyId(loginUser.getCompanyId());
            sysLog.setCompanyName(loginUser.getCompanyName());
            sysLogService.save(sysLog);
            //目标方法的执行结果一定要返回
            return result;
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}
